﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Drawing.Imaging;

namespace ZombieMapEditor
{
    public partial class ZombieMapEditor : Form
    {
        List<Wall> Walls;
        List<Spawner> Spawners;
        List<Player> Players;
        MapObject Selected;
        MapObject Dragging;
        public ZombieMapEditor()
        {
            InitializeComponent();
            Walls = new List<Wall>();
            Spawners = new List<Spawner>();
            Players = new List<Player>();
        }

        private void loadBackButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog diag = new OpenFileDialog();
            diag.Filter = "PNG Imagess|*.png";
            diag.Title = "Choose Background Image";
            if (diag.ShowDialog() == DialogResult.OK)
            {
                pictureBox1.Image = Bitmap.FromFile(diag.FileName);
            }
        }

        private void pictureBox1_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            if (Dragging != null)
                Dragging.Position = pictureBox1.PointToClient(MousePosition);
            foreach (Wall w in Walls)
                w.Draw(g);
            foreach (Spawner s in Spawners)
                s.Draw(g);
            foreach (Player p in Players)
                p.Draw(g);
            pictureBox1.Invalidate();
        }

        private void splitContainer1_Panel2_MouseDown(object sender, MouseEventArgs e)
        {
            Point mPos = MousePosition;
            pictureBox1.Focus();
            listBox1.SelectedIndexChanged -= new EventHandler(listBox1_SelectedIndexChanged);
            listBox1.SelectedIndex = -1;
            listBox1.SelectedIndexChanged += new EventHandler(listBox1_SelectedIndexChanged);
            if (Selected != null)
            {
                Selected.Selected = false;
                Selected = null;
            }
            foreach (Wall w in Walls)
            {
                if (w.P1.PointCollision(pictureBox1.PointToClient(mPos)))
                {
                    Selected = w.P1;
                    Selected.Selected = true;
                    Dragging = w.P1;
                    foreach (int i in w.Allowed)
                        listBox1.SelectedIndices.Add(i);
                    break;
                }
                if (w.P2.PointCollision(pictureBox1.PointToClient(mPos)))
                {
                    Selected = w.P2;
                    Selected.Selected = true;
                    Dragging = w.P2;
                    foreach (int i in w.Allowed)
                        listBox1.SelectedIndices.Add(i);
                    break;
                }
            }
            foreach (Spawner s in Spawners)
            {
                if (s.PointCollision(pictureBox1.PointToClient(mPos)))
                {
                    Selected = s;
                    Selected.Selected = true;
                    Dragging = s;
                    break;
                }
            }
            foreach (Player p in Players)
            {
                if (p.PointCollision(pictureBox1.PointToClient(mPos)))
                {
                    Selected = p;
                    Selected.Selected = true;
                    Dragging = p;
                    break;
                }
            }
            listBox1.Enabled = delWallButton.Enabled = Selected is WallPoint;
            delSpawnerButton.Enabled = Selected is Spawner;
            delPlayerButton.Enabled = Selected is Player;
        }

        private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (Selected is WallPoint)
            {
                int[] i = new int[listBox1.SelectedIndices.Count];
                listBox1.SelectedIndices.CopyTo(i, 0);
                ((WallPoint)Selected).Container.Allowed = new List<int>(i);
            }
        }

        private void splitContainer1_Panel2_MouseUp(object sender, MouseEventArgs e)
        {
            Dragging = null;
        }

        private void splitContainer1_Panel2_MouseLeave(object sender, EventArgs e)
        {
            splitContainer1_Panel2_MouseUp(null, null);
        }

        private void newWallButton_Click(object sender, EventArgs e)
        {
            Wall w = new Wall();
            PointF pos;
            if (Selected == null)
                pos = Point.Subtract(new Point(Math.Min(pictureBox1.Size.Width / 2, splitContainer1.Panel2.ClientSize.Width / 2), Math.Min(pictureBox1.Size.Height / 2, splitContainer1.Panel2.ClientSize.Height / 2)), new Size(splitContainer1.Panel2.AutoScrollPosition));
            else
            {
                pos = Selected.Position;
                Selected.Selected = false;
            }
            w.P1 = new WallPoint(pos, w);
            w.P2 = new WallPoint(pos, w);
            if (Selected is WallPoint)
                w.Allowed = ((WallPoint)Selected).Container.Allowed;
            else
                w.Allowed = new List<int>();
            Selected = w.P1;
            Selected.Selected = true;
            Walls.Add(w);
            pictureBox1.Focus();
            delWallButton.Enabled = false;
        }

        private void delWallButton_Click(object sender, EventArgs e)
        {
            Walls.Remove(((WallPoint)Selected).Container);
            listBox1.SelectedIndex = -1;
            listBox1.Enabled = false;
            Selected = null;
        }

        private void pictureBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
        {
            if (Selected != null)
            {
                if (Selected is WallPoint && e.Shift)
                {
                    Wall w = ((WallPoint)Selected).Container;
                    if (e.KeyCode == Keys.W || e.KeyCode == Keys.Up)
                    {
                        w.P1.Position = new PointF(w.P1.Position.X, w.P1.Position.Y - 1f);
                        w.P2.Position = new PointF(w.P2.Position.X, w.P2.Position.Y - 1f);
                    }
                    if (e.KeyCode == Keys.S || e.KeyCode == Keys.Down)
                    {
                        w.P1.Position = new PointF(w.P1.Position.X, w.P1.Position.Y + 1f);
                        w.P2.Position = new PointF(w.P2.Position.X, w.P2.Position.Y + 1f);
                    }
                    if (e.KeyCode == Keys.A || e.KeyCode == Keys.Left)
                    {
                        w.P1.Position = new PointF(w.P1.Position.X - 1f, w.P1.Position.Y);
                        w.P2.Position = new PointF(w.P2.Position.X - 1f, w.P2.Position.Y);
                    }
                    if (e.KeyCode == Keys.D || e.KeyCode == Keys.Right)
                    {
                        w.P1.Position = new PointF(w.P1.Position.X + 1f, w.P1.Position.Y);
                        w.P2.Position = new PointF(w.P2.Position.X + 1f, w.P2.Position.Y);
                    }
                }
                else
                {
                    if (e.KeyCode == Keys.W || e.KeyCode == Keys.Up)
                        Selected.Position = new PointF(Selected.Position.X, Selected.Position.Y - 1f);
                    if (e.KeyCode == Keys.S || e.KeyCode == Keys.Down)
                        Selected.Position = new PointF(Selected.Position.X, Selected.Position.Y + 1f);
                    if (e.KeyCode == Keys.A || e.KeyCode == Keys.Left)
                        Selected.Position = new PointF(Selected.Position.X - 1f, Selected.Position.Y);
                    if (e.KeyCode == Keys.D || e.KeyCode == Keys.Right)
                        Selected.Position = new PointF(Selected.Position.X + 1f, Selected.Position.Y);
                }
            }
            pictureBox1.Focus();
        }

        private void newSpawnerButton_Click(object sender, EventArgs e)
        {
            Spawner s = new Spawner();
            PointF pos;
            if (Selected == null)
                pos = Point.Subtract(new Point(Math.Min(pictureBox1.Size.Width / 2, splitContainer1.Panel2.ClientSize.Width / 2), Math.Min(pictureBox1.Size.Height / 2, splitContainer1.Panel2.ClientSize.Height / 2)), new Size(splitContainer1.Panel2.AutoScrollPosition));
            else
            {
                pos = Selected.Position;
                Selected.Selected = false;
            }
            s.Position = pos;
            s.Selected = true;
            Selected = s;
            Spawners.Add(s);
            pictureBox1.Focus();
            delSpawnerButton.Enabled = false;
        }

        private void delSpawnerButton_Click(object sender, EventArgs e)
        {
            Spawners.Remove((Spawner)Selected);
            Selected = null;
        }

        private void newPlayerButton_Click(object sender, EventArgs e)
        {
            Player s = new Player();
            PointF pos;
            if (Selected == null)
                pos = Point.Subtract(new Point(Math.Min(pictureBox1.Size.Width / 2, splitContainer1.Panel2.ClientSize.Width / 2), Math.Min(pictureBox1.Size.Height / 2, splitContainer1.Panel2.ClientSize.Height / 2)), new Size(splitContainer1.Panel2.AutoScrollPosition));
            else
            {
                pos = Selected.Position;
                Selected.Selected = false;
            }
            s.Position = pos;
            s.Selected = true;
            Selected = s;
            Players.Add(s);
            pictureBox1.Focus();
            delPlayerButton.Enabled = false;
        }

        private void delPlayerButton_Click(object sender, EventArgs e)
        {
            Players.Remove((Player)Selected);
            Selected = null;
        }

        private void saveButton_Click(object sender, EventArgs e)
        {
            float d;
            if (float.TryParse(dropTextBox.Text, out d))
            {
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Filter = "Project Undead World File (*.puw)|*.puw";
                sfd.Title = "Choose file location";
                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    FileStream fs = File.Open(sfd.FileName, FileMode.Append);
                    BinaryWriter writer = new BinaryWriter(fs);
                    writer.Write(d);
                    foreach (Wall w in Walls)
                    {
                        writer.Write((byte)1);
                        writer.Write(w.P1.Position.X);
                        writer.Write(w.P1.Position.Y);
                        writer.Write(w.P2.Position.X);
                        writer.Write(w.P2.Position.Y);
                        writer.Write(w.Allowed.Count);
                        for (int i = 0; i < w.Allowed.Count; i++)
                        {
                            writer.Write(w.Allowed[i]);
                        }
                    }
                    writer.Write((byte)0);
                    foreach (Spawner s in Spawners)
                    {
                        writer.Write((byte)1);
                        writer.Write(s.Position.X);
                        writer.Write(s.Position.Y);
                    }
                    writer.Write((byte)0);
                    foreach (Player p in Players)
                    {
                        writer.Write((byte)1);
                        writer.Write(p.Position.X);
                        writer.Write(p.Position.Y);
                    }
                    writer.Write((byte)0);
                    pictureBox1.Image.Save(fs, ImageFormat.Png);
                    writer.Close();
                    fs.Close();
                }
            }
            else
                MessageBox.Show("NO!");
        }

        private void loadMapButton_Click(object sender, EventArgs e)
        {
            OpenFileDialog diag = new OpenFileDialog();
            diag.Filter = "Project Undead World File (*.puw)|*.puw";
            diag.Title = "Choose World";
            if (diag.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                FileStream str = File.Open(diag.FileName, FileMode.Open);
                BinaryReader reader = new BinaryReader(str);
                dropTextBox.Text = reader.ReadSingle().ToString();
                while (reader.ReadByte() != 0)
                {
                    Wall w = new Wall();
                    w.P1 = new WallPoint(new PointF(reader.ReadSingle(), reader.ReadSingle()), w);
                    w.P2 = new WallPoint(new PointF(reader.ReadSingle(), reader.ReadSingle()), w);
                    w.Allowed = new List<int>();
                    int l = reader.ReadInt32();
                    for (int i = 0; i < l; i++)
                        w.Allowed.Add(reader.ReadInt32());
                    Walls.Add(w);
                }
                while (reader.ReadByte() != 0)
                {
                    Spawner s = new Spawner();
                    s.Position = new PointF(reader.ReadSingle(), reader.ReadSingle());
                    Spawners.Add(s);
                }
                while (reader.ReadByte() != 0)
                {
                    Player s = new Player();
                    s.Position = new PointF(reader.ReadSingle(), reader.ReadSingle());
                    Players.Add(s);
                }
                byte[] imgData = reader.ReadBytes((int)(str.Length - str.Position));
                using (MemoryStream str2 = new MemoryStream(imgData))
                    pictureBox1.Image = Image.FromStream(str2);
                reader.Close();
                str.Close();
            }
        }
    }
}
